﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ServiceManager.Utils;
using ServiceStack.Redis;
namespace QuotationService.RealtimeQuotation
{

    /// <summary>
    /// 实时行情信息通道
    /// </summary>
    [DebuggerNonUserCode]
    internal static class QuotationInfoChannel
    {
        /// <summary>
        /// 保存实时行情信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="quotInfo"></param>
        /// <param name="preserveHistory"></param>
        /// <returns></returns>
        public static bool Update(QuotationSource source, string code, byte[] quotInfo, bool preserveHistory = false)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (quotInfo == null || quotInfo.Length == 0)
                throw new ArgumentNullException("quotInfo");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Append&Update QuotationInfo", 1))
            {
                using (var conn = publisher.GetNeedDisposedConnection())
                {
                    using (var pipeline = conn.CreatePipeline())
                    {
                        if (preserveHistory)
                        {
                            //历史快照保存
                            publisher.Append(source.ToFormatString() + ":" + QuotationDataType.QuotationList.ToFormatString() + ":" + code, quotInfo, pipeline);
                        }
                        //最新快照更新并发布
                        publisher.Update(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString(), code, quotInfo, pipeline);

                        pipeline.Flush();

                        return true;
                    }
                }
            }
        }

        /// <summary>
        /// 保存实时行情中的逐笔信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="tickInfo"></param>
        /// <returns></returns>
        public static bool UpdateTick(QuotationSource source, string code, byte[] tickInfo)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (tickInfo == null || tickInfo.Length == 0)
                throw new ArgumentNullException("tickInfo");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Append TickInfo", 1))
            {
                return publisher.Append(source.ToFormatString() + ":" + QuotationDataType.TickList.ToFormatString() + ":" + code, tickInfo);
            }
        }

        /// <summary>
        /// 发布实时行情信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="quotInfo"></param>
        /// <returns></returns>
        public static bool Publish(QuotationSource source, string code, byte[] quotInfo)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (quotInfo == null || quotInfo.Length == 0)
                throw new ArgumentNullException("quotInfo");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Publish QuotationInfo", 1))
            {
                //最新快照更新并发布
                return publisher.Publish(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString() + ":" + code.PadLeft(10, '#'), quotInfo);
            }
        }



        /// <summary>
        /// 发布实时行情信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="authCode"></param>
        /// <param name="quotInfo"></param>
        /// <returns></returns>
        public static bool Publish(QuotationSource source, string code, string authCode, byte[] quotInfo)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (quotInfo == null || quotInfo.Length == 0)
                throw new ArgumentNullException("quotInfo");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Publish QuotationInfo", 1))
            {
                //最新快照更新并发布
                return publisher.Publish(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString() + ":" + code.PadLeft(10, '#') + ":" + authCode.PadLeft(20, '#'), quotInfo);
            }
        }



        /// <summary>
        /// 获取所有商品的实时行情
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<byte[]> GetAll(QuotationSource source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("GetAll QuotationInfo Snapshot", 1))
                {
                    var retValues = (conn as RedisClient).HVals(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString());
                    if (retValues == null)
                        return null;

                    return retValues.ToList();
                }
            }
        }

        /// <summary>
        /// 删除所有商品的实时行情
        /// </summary>
        /// <param name="source"></param>
        public static bool ClearAll(QuotationSource source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("ClearAll QuotationInfo", 1))
            {
                //删除所有商品的实时行情
                if (!publisher.Delete(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString()))
                    return false;

                //删除所有商品的历史行情
                var keys = publisher.SearchKeys(source.ToFormatString() + ":" + QuotationDataType.QuotationList.ToFormatString() + ":*").ToArray();
                if (keys.Length > 0 && !publisher.Delete(keys))
                    return false;

                //删除所有商品的历史逐笔信息
                keys = publisher.SearchKeys(source.ToFormatString() + ":" + QuotationDataType.TickList.ToFormatString() + ":*").ToArray();
                if (keys.Length > 0 && !publisher.Delete(keys))
                    return false;
            }

            return true;
        }

        /// <summary>
        /// 获取单只商品的实时行情
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static byte[] Get(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get Single QuotationInfo", 1))
                {
                    return (conn as RedisClient).HGet(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString(),
                                                        code.ToUtf8Bytes());
                }
            }
        }

        /// <summary>
        /// 删除单只商品的行情信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool Clear(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Clear Single QuotationInfo", 1))
            {
                return publisher.Delete(source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString(), code);
            }
        }

        /// <summary>
        /// 获取单只商品的历史行情
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static List<byte[]> GetAll(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get Single QuotationList", 1))
                {
                    var retValues = (conn as RedisClient).LRange(source.ToFormatString() + ":" + QuotationDataType.QuotationList.ToFormatString() + ":" + code, 0, -1);
                    if (retValues == null)
                        return null;

                    return retValues.ToList();
                }
            }
        }

        /// <summary>
        /// 获取单只商品的历史逐笔信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static List<byte[]> GetTicks(QuotationSource source, string code, int start = 0, int end = -1)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get Single TickList", 1))
                {
                    var retValues = (conn as RedisClient).LRange(source.ToFormatString() + ":" + QuotationDataType.TickList.ToFormatString() + ":" + code, start, end);
                    if (retValues == null)
                        return null;

                    return retValues.ToList();
                }
            }
        }

        /// <summary>
        /// 删除单只商品的历史行情
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        public static bool ClearAll(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Clear Single QuotationList&TickList", 1))
            {
                using (var conn = publisher.GetNeedDisposedConnection())
                {
                    using (var pipeline = conn.CreatePipeline())
                    {
                        //删除历史行情
                        publisher.Delete(source.ToFormatString() + ":" + QuotationDataType.QuotationList.ToFormatString() + ":" + code, pipeline);

                        //删除历史逐笔信息
                        publisher.Delete(source.ToFormatString() + ":" + QuotationDataType.TickList.ToFormatString() + ":" + code, pipeline);

                        pipeline.Flush();

                        return true;
                    }
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string ToSubscribeChannel(QuotationSource source, string code = "")
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                code = "??????????";

            return source.ToFormatString() + ":" + QuotationDataType.Quotation.ToFormatString() + ":" + code.PadLeft(10, '#');
        }
    }



}
